#include "qt_widget_application.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
#include <QComboBox>
#include <QPushButton>
#include <QTextEdit>
#include <QSerialPortInfo>

QtWidgetApplication::QtWidgetApplication(QWidget *parent)
    : QMainWindow(parent)
{
    // Create UI elements
    m_serialPortComboBox = new QComboBox(this);
    m_baudRateComboBox = new QComboBox(this);
    m_dataBitsComboBox = new QComboBox(this);
    m_parityComboBox = new QComboBox(this);
    m_stopBitsComboBox = new QComboBox(this);
    m_flowControlComboBox = new QComboBox(this);
    m_openButton = new QPushButton(tr("打开串口"), this);
    m_closeButton = new QPushButton(tr("关闭串口"), this);
    m_sendButton = new QPushButton(tr("发送"), this);
    m_receiveTextEdit = new QTextEdit(this);
    m_sendTextEdit = new QTextEdit(this);
    
    // Setup layout
    QWidget *centralWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
    
    // Serial port settings
    QHBoxLayout *settingsLayout = new QHBoxLayout();
    settingsLayout->addWidget(new QLabel(tr("端口:")));
    settingsLayout->addWidget(m_serialPortComboBox);
    settingsLayout->addWidget(new QLabel(tr("波特率:")));
    settingsLayout->addWidget(m_baudRateComboBox);
    settingsLayout->addWidget(new QLabel(tr("数据位:")));
    settingsLayout->addWidget(m_dataBitsComboBox);
    settingsLayout->addWidget(new QLabel(tr("校验位:")));
    settingsLayout->addWidget(m_parityComboBox);
    settingsLayout->addWidget(new QLabel(tr("停止位:")));
    settingsLayout->addWidget(m_stopBitsComboBox);
    settingsLayout->addWidget(new QLabel(tr("流控制:")));
    settingsLayout->addWidget(m_flowControlComboBox);
    settingsLayout->addWidget(m_openButton);
    settingsLayout->addWidget(m_closeButton);
    
    // Data area
    QHBoxLayout *dataLayout = new QHBoxLayout();
    QVBoxLayout *receiveLayout = new QVBoxLayout();
    receiveLayout->addWidget(new QLabel(tr("接收数据:")));
    receiveLayout->addWidget(m_receiveTextEdit);
    
    QVBoxLayout *sendLayout = new QVBoxLayout();
    sendLayout->addWidget(new QLabel(tr("发送数据:")));
    sendLayout->addWidget(m_sendTextEdit);
    sendLayout->addWidget(m_sendButton);
    
    dataLayout->addLayout(receiveLayout);
    dataLayout->addLayout(sendLayout);
    
    mainLayout->addLayout(settingsLayout);
    mainLayout->addLayout(dataLayout);
    
    centralWidget->setLayout(mainLayout);
    setCentralWidget(centralWidget);
    
    // Initialize serial port settings
    initSerialPortSettings();
    initActionsConnections();
    
    m_closeButton->setEnabled(false);
    m_sendButton->setEnabled(false);
}

QtWidgetApplication::~QtWidgetApplication()
{
    if (m_serial && m_serial->isOpen())
        m_serial->close();
    delete m_serial;
}

void QtWidgetApplication::initSerialPortSettings()
{
    // Populate serial port list
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        m_serialPortComboBox->addItem(info.portName());
    
    // Baud rate
    m_baudRateComboBox->addItem("1200", QSerialPort::Baud1200);
    m_baudRateComboBox->addItem("2400", QSerialPort::Baud2400);
    m_baudRateComboBox->addItem("4800", QSerialPort::Baud4800);
    m_baudRateComboBox->addItem("9600", QSerialPort::Baud9600);
    m_baudRateComboBox->addItem("19200", QSerialPort::Baud19200);
    m_baudRateComboBox->addItem("38400", QSerialPort::Baud38400);
    m_baudRateComboBox->addItem("57600", QSerialPort::Baud57600);
    m_baudRateComboBox->addItem("115200", QSerialPort::Baud115200);
    m_baudRateComboBox->setCurrentIndex(3); // Default to 9600
    
    // Data bits
    m_dataBitsComboBox->addItem("5", QSerialPort::Data5);
    m_dataBitsComboBox->addItem("6", QSerialPort::Data6);
    m_dataBitsComboBox->addItem("7", QSerialPort::Data7);
    m_dataBitsComboBox->addItem("8", QSerialPort::Data8);
    m_dataBitsComboBox->setCurrentIndex(3); // Default to 8
    
    // Parity
    m_parityComboBox->addItem("None", QSerialPort::NoParity);
    m_parityComboBox->addItem("Even", QSerialPort::EvenParity);
    m_parityComboBox->addItem("Odd", QSerialPort::OddParity);
    m_parityComboBox->addItem("Space", QSerialPort::SpaceParity);
    m_parityComboBox->addItem("Mark", QSerialPort::MarkParity);
    m_parityComboBox->setCurrentIndex(0); // Default to None
    
    // Stop bits
    m_stopBitsComboBox->addItem("1", QSerialPort::OneStop);
    m_stopBitsComboBox->addItem("1.5", QSerialPort::OneAndHalfStop);
    m_stopBitsComboBox->addItem("2", QSerialPort::TwoStop);
    m_stopBitsComboBox->setCurrentIndex(0); // Default to 1
    
    // Flow control
    m_flowControlComboBox->addItem("None", QSerialPort::NoFlowControl);
    m_flowControlComboBox->addItem("RTS/CTS", QSerialPort::HardwareControl);
    m_flowControlComboBox->addItem("XON/XOFF", QSerialPort::SoftwareControl);
    m_flowControlComboBox->setCurrentIndex(0); // Default to None
}

void QtWidgetApplication::initActionsConnections()
{
    connect(m_openButton, &QPushButton::clicked, this, &QtWidgetApplication::openSerialPort);
    connect(m_closeButton, &QPushButton::clicked, this, &QtWidgetApplication::closeSerialPort);
    connect(m_sendButton, &QPushButton::clicked, this, &QtWidgetApplication::writeData);
}

void QtWidgetApplication::openSerialPort()
{
    m_serial = new QSerialPort(this);
    m_serial->setPortName(m_serialPortComboBox->currentText());
    m_serial->setBaudRate(m_baudRateComboBox->currentData().toInt());
    m_serial->setDataBits(static_cast<QSerialPort::DataBits>(m_dataBitsComboBox->currentData().toInt()));
    m_serial->setParity(static_cast<QSerialPort::Parity>(m_parityComboBox->currentData().toInt()));
    m_serial->setStopBits(static_cast<QSerialPort::StopBits>(m_stopBitsComboBox->currentData().toInt()));
    m_serial->setFlowControl(static_cast<QSerialPort::FlowControl>(m_flowControlComboBox->currentData().toInt()));
    
    if (m_serial->open(QIODevice::ReadWrite)) {
        connect(m_serial, &QSerialPort::readyRead, this, &QtWidgetApplication::readData);
        connect(m_serial, &QSerialPort::errorOccurred, this, &QtWidgetApplication::handleError);
        
        m_openButton->setEnabled(false);
        m_closeButton->setEnabled(true);
        m_sendButton->setEnabled(true);
    } else {
        QMessageBox::critical(this, tr("错误"), tr("无法打开串口：%1").arg(m_serial->errorString()));
        delete m_serial;
        m_serial = nullptr;
    }
}

void QtWidgetApplication::closeSerialPort()
{
    if (m_serial && m_serial->isOpen()) {
        m_serial->close();
        delete m_serial;
        m_serial = nullptr;
    }
    
    m_openButton->setEnabled(true);
    m_closeButton->setEnabled(false);
    m_sendButton->setEnabled(false);
}

void QtWidgetApplication::writeData()
{
    if (m_serial && m_serial->isOpen()) {
        QByteArray data = m_sendTextEdit->toPlainText().toUtf8();
        m_serial->write(data);
    }
}

void QtWidgetApplication::readData()
{
    if (m_serial && m_serial->isOpen()) {
        QByteArray data = m_serial->readAll();
        m_receiveTextEdit->append(QString::fromUtf8(data));
    }
}

void QtWidgetApplication::handleError(QSerialPort::SerialPortError error)
{
    if (error == QSerialPort::ResourceError) {
        QMessageBox::critical(this, tr("严重错误"), tr("串口错误：%1").arg(m_serial->errorString()));
        closeSerialPort();
    }
}
